# coding=utf-8
import os
import time
import uuid

from django.conf import settings
from django.http import HttpResponse, StreamingHttpResponse
from django.shortcuts import render
from django.views.decorators.cache import cache_page

from apps.common.requests import *
import base64

from django.http import FileResponse

from document.services.document import info_document, info_single_document, update_document
from document.services.documentpath import list_docpath
from document.services.folder import info_folder, update_folder
from document.services.folderpath import path_DFS, info_folderpath, path_DFS_cab, path_UDFS_cab, add_folderpath, \
    path_BFS_tree, update_folderpath
from apps.organize_manager.service import get_all_orguser
from service import *
from django.core.cache import cache
from services.documentpath import *


def file_download(request):
    """
    文件下载
    :param request:
    :return:
    """
    try:
        id = request.GET.get("id")
        document = info_single_document({"id": id})

        file = open(document.storage, 'rb')
        response = FileResponse(file)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{}"'.format(document.name)
        return response
    except Exception as e:
        print e
        return err_requests("505")


def file_upload(request):
    """
    文件上传
    :param request:
    :return:
    """
    if request.method == 'POST':
        file = request.FILES['file']
        if cache.has_key(file.name):
            fileName = cache.get(file.name)
        else:
            path = os.path.join(settings.MEDIA_ROOT, str(uuid.uuid4()))
            try:
                os.mkdir(path)
            except:
                pass
            fileName = path + "/" + file.name
        cache.set(file.name, fileName, 60 * 15)
        print(fileName)
        with open(fileName, 'wb') as f:
            for file_part in file.chunks():
                f.write(file_part)
        return success_requests({"fileName": fileName})
    else:
        return err_requests('method 方法 错误')


def index_view(request, meta):
    """
    初始界面
    :param request:
    :param meta:
    :return:
    """
    if meta:
        org_users = get_all_orguser()
        return render(request, template_name="document/list.html",
                      context={"org_id": meta, "classes": None, "org_users": org_users})
    return render(request, template_name="document/list.html")


def index_classes_view(request, meta):
    """
    初始界面
    :param request:
    :param meta:
    :return:
    """
    if meta:
        return render(request, template_name="document/clalist.html",
                      context={"org_id": None, "classes": meta, "org_users": get_all_orguser()})
    return render(request, template_name="document/clalist.html")


def uplade_view(request, meta):
    """
    上传界面
    :param request:
    :param meta:
    :return:
    """
    if meta:
        return render(request, template_name="document/uploader.html", context={"org_id": meta})
    return render(request, template_name="document/uploader.html")


def create_folder(request):
    """
    创建文件夹
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"name": "foldername"})
        if isinstance(params, JsonResponse):
            return params

        path_params = get_params(body,
                                 null_params={"parent_folder": "folder_id", "org": "org_id", "classes": "classes"}, )
        if isinstance(path_params, JsonResponse):
            return path_params

        create_user = session_getuser(request)
        if settings.DEBUG:
            create_user = CloudAuthUser.objects.get(id=1)
        if isinstance(create_user, Errorquery):
            return err_requests("500", create_user.msg)

        params["create_user"] = create_user
        from services.folder import add_folder
        result = add_folder(params)

        if isinstance(result, Errorquery):
            return err_requests("500", result.msg)

        from services.folderpath import add_folderpath
        from services.folder import info_folder
        path_params["folder"] = result
        if path_params["parent_folder"]:
            path_params["parent_folder"] = info_folder({"id": path_params["parent_folder"]})
        result = add_folderpath(path_params)
        if isinstance(result, Errorquery):
            return err_requests("500", result.msg)
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def create_document_single(request, body):
    """
    添加一个文件
    :param request:
    :param body:
    :return:
    """
    params = get_params(body, {"storage": "storage", "name": "name"}, {"size": "size", "ext": "ext"})
    if isinstance(params, JsonResponse):
        return params

    path_params = get_params(body, null_params={"folder": "folder_id", "org": "org_id", "classes": "classes"}, )
    if isinstance(path_params, JsonResponse):
        return path_params

    create_user = session_getuser(request)
    if settings.DEBUG:
        create_user = CloudAuthUser.objects.get(id=1)
    if isinstance(create_user, Errorquery):
        return err_requests("500", create_user.msg)

    params["create_user"] = create_user
    from services.document import add_document
    result = add_document(params)
    if isinstance(result, Errorquery):
        return err_requests("500", result.msg)

    from services.documentpath import add_docpath
    path_params["document"] = result
    if path_params["folder"]:
        path_params["folder"] = info_folder({"id": path_params["folder"]})
    result = add_docpath(path_params)
    if isinstance(result, Errorquery):
        return err_requests("500", result.msg)


def create_document(request):
    """
    创建文件
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        documents = get_params(body, {"fileList": "fileList"})

        for document in documents.get("fileList"):
            create_document_single(request, document)
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def document_list_api(request):
    """
    文档列表
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body

        # 获取文件参数
        params = get_params_exitnull(body, {"folder": "folder_id"}, null_params={"org": "org_id", "classes": "classes"})
        if isinstance(params, JsonResponse):
            return params
        params["document__in_trash"] = False
        from services.document import list_document
        documents = list_docpath(params)
        if isinstance(documents, Errorquery):
            return err_requests("500", documents.msg)

        # 获取文件夹参数
        folder_params = get_params_exitnull(body, {"parent_folder": "folder_id"},
                                            null_params={"org": "org_id", "classes": "classes"})
        if isinstance(folder_params, JsonResponse):
            return folder_params
        params["parent_folder__in_trash"] = False
        params["folder__in_trash"] = False
        from services.folderpath import list_folderpath
        folders = list_folderpath(folder_params)
        if isinstance(folders, Errorquery):
            return err_requests("500", folders.msg)

        objects_list = []
        for folder in folders:
            folder_object = {}
            folder_object["name"] = folder.folder.name
            folder_object["create_time"] = str(folder.folder.create_time).split("-")[0]
            folder_object["create_user"] = folder.folder.create_user.realname
            folder_object["secrecy"] = folder.folder.secrecy
            folder_object["path_id"] = None
            if folder.parent_folder:
                folder_object["path_id"] = folder.parent_folder.id
            folder_object["size"] = "-"
            folder_object["count"] = list_docpath({"folder": folder.folder.id}).count()
            folder_object["id"] = folder.folder.id
            folder_object["description"] = folder.folder.description
            folder_object["is_doc"] = False
            folder_object["uid"] = str(uuid.uuid4()).replace("-", "")
            objects_list.append(folder_object)

        for document in documents:
            document_object = dict()
            document_object["name"] = document.document.name
            document_object["id"] = document.document.id
            document_object["path_id"] = document.id
            document_object["create_time"] = str(document.document.create_time).split("-")[0]
            document_object["create_user"] = document.document.create_user.realname
            document_object["secrecy"] = document.document.secrecy
            document_object["size"] = document.document.size
            document_object["count"] = 1
            document_object["description"] = document.document.description
            document_object["is_doc"] = True
            document_object["ext"] = None
            document_object["uid"] = str(uuid.uuid4()).replace("-", "")
            if document.document.ext:
                document_object["ext"] = document.document.ext
            if document.document.had_archive:
                document_object["archived"] = "已归档"
            else:
                document_object["archived"] = "未归档"
            objects_list.append(document_object)

        folderpaths = []
        if folder_params.get("parent_folder"):
            path_DFS({"folder__id": folder_params["parent_folder"], "classes": None}, folderpaths)
        folderpaths.append({"name": "根目录", "id": None})
        result = {"totalDoc": objects_list, "totalPath": folderpaths[::-1]}
        return success_requests(result)
    except Exception as e:
        print e
        return err_requests("500", str(e))


def query_single_docment(request):
    """
    文档列表
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body

        # 获取文件参数
        params = get_params_exitnull(body,
                                     null_params={"name__icontains": "title",
                                                  "create_user__realname__icontains": "charge"})
        if isinstance(params, JsonResponse):
            return params
        from services.document import list_document
        documents = list_document(params)
        if isinstance(documents, Errorquery):
            return err_requests("500", documents.msg)

        # 获取文件夹参数
        folder_params = get_params_exitnull(body, null_params={"name__icontains": "title",
                                                               "create_user__realname__icontains": "charge"})
        if isinstance(folder_params, JsonResponse):
            return folder_params
        from services.folder import list_folder
        folders = list_folder(folder_params)
        if isinstance(folders, Errorquery):
            return err_requests("500", folders.msg)

        objects_list = []
        for folder in folders:
            folder_object = {}
            folder_object["name"] = folder.name
            folder_object["create_time"] = str(folder.create_time).split("-")[0]
            folder_object["create_user"] = folder.create_user.realname
            folder_object["secrecy"] = folder.secrecy
            folder_object["path_id"] = None
            folder_object["size"] = "-"
            folder_object["count"] = list_docpath({"folder": folder.id}).count()
            folder_object["id"] = folder.id
            folder_object["description"] = folder.description
            folder_object["is_doc"] = False
            folder_object["uid"] = str(uuid.uuid4()).replace("-", "")
            objects_list.append(folder_object)

        for document in documents:
            document_object = dict()
            document_object["name"] = document.name
            document_object["id"] = document.id
            document_object["path_id"] = document.id
            document_object["create_time"] = str(document.create_time).split("-")[0]
            document_object["create_user"] = document.create_user.realname
            document_object["secrecy"] = document.secrecy
            document_object["size"] = document.size
            document_object["count"] = 1
            document_object["description"] = document.description
            document_object["is_doc"] = True
            document_object["ext"] = None
            document_object["uid"] = str(uuid.uuid4()).replace("-", "")
            if document.ext:
                document_object["ext"] = document.ext
            if document.had_archive:
                document_object["archived"] = "已归档"
            else:
                document_object["archived"] = "未归档"
            objects_list.append(document_object)

        return success_requests(objects_list)
    except Exception as e:
        print e
        return err_requests("500", str(e))


def query_filter_docment(request):
    """
    文档列表
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body

        # 获取文件参数
        params = get_params_exitnull(body,
                                     null_params={"name__icontains": "title", "create_time__gt": "startTime",
                                                  "create_time__lt": "overTime",
                                                  "create_user__realname__icontains": "charge",
                                                  "create_time__year": "year"})
        if isinstance(params, JsonResponse):
            return params
        from services.document import list_document
        documents = list_document(params)
        if isinstance(documents, Errorquery):
            return err_requests("500", documents.msg)

        # 获取文件夹参数
        folder_params = get_params_exitnull(body,
                                            null_params={"name__icontains": "title", "create_time__gt": "startTime",
                                                         "create_time__lt": "overTime",
                                                         "create_user__realname__icontains": "charge",
                                                         "create_time__year": "year"})
        if isinstance(folder_params, JsonResponse):
            return folder_params
        from services.folder import list_folder
        folders = list_folder(folder_params)
        if isinstance(folders, Errorquery):
            return err_requests("500", folders.msg)

        objects_list = []
        for folder in folders:
            folder_object = {}
            folder_object["name"] = folder.name
            folder_object["create_time"] = str(folder.create_time).split("-")[0]
            folder_object["create_user"] = folder.create_user.realname
            folder_object["secrecy"] = folder.secrecy
            folder_object["path_id"] = None
            folder_object["size"] = "-"
            folder_object["count"] = list_docpath({"folder": folder.id}).count()
            folder_object["id"] = folder.id
            folder_object["description"] = folder.description
            folder_object["is_doc"] = False
            folder_object["uid"] = str(uuid.uuid4()).replace("-", "")
            objects_list.append(folder_object)

        for document in documents:
            document_object = dict()
            document_object["name"] = document.name
            document_object["id"] = document.id
            document_object["path_id"] = document.id
            document_object["create_time"] = str(document.create_time).split("-")[0]
            document_object["create_user"] = document.create_user.realname
            document_object["secrecy"] = document.secrecy
            document_object["size"] = document.size
            document_object["count"] = 1
            document_object["description"] = document.description
            document_object["is_doc"] = True
            document_object["ext"] = None
            document_object["uid"] = str(uuid.uuid4()).replace("-", "")
            if document.ext:
                document_object["ext"] = document.ext
            if document.had_archive:
                document_object["archived"] = "已归档"
            else:
                document_object["archived"] = "未归档"
            objects_list.append(document_object)

        return success_requests(objects_list)
    except Exception as e:
        print e
        return err_requests("500", str(e))


def archive_document_core(request, params):
    """
    文件归档核心
    :param request:
    :return:
    """
    try:
        if params["is_doc"]:
            docpath = info_docpath({"document": params["id"], "classes": None})
            object = add_docpath({"document": docpath.document, "folder": docpath.folder, "classes": params["classes"]})
            update_document({"id": params["id"]}, {"had_archive": True})
            if docpath.folder:
                path_DFS_cab({"folder": docpath.folder, "classes": None}, object.classes)
        else:
            folderpath = info_folderpath({"folder": params["id"], "classes": None})
            object = add_folderpath(
                {"folder": folderpath.folder, "parent_folder": folderpath.parent_folder, "classes": params["classes"]})
            if folderpath.folder:
                path_DFS_cab({"folder": folderpath.parent_folder, "classes": None}, params["classes"])
            path_UDFS_cab({"parent_folder": folderpath.folder, "classes": None}, {"folder": folderpath.folder},
                          params["classes"])
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def archive_document(request):
    """
    文件归档
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"classes": "chance", "docs": "id"})
        if isinstance(params, JsonResponse):
            return params

        for document in params.get("docs"):
            document["classes"] = params.get("classes")
            archive_document_core(request, document)
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def document_single_delete_api(request):
    """
    删除单个文件
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"id": "id", "is_doc": "is_doc"}, {"in_trash": "in_trash"}, in_trash=True)
        if isinstance(params, JsonResponse):
            return params
        from services.document import del_document
        if params["is_doc"]:
            result = update_document({"id": params['id']}, {"in_trash": True})
        else:
            result = update_folder({"id": params['id']}, {"in_trash": True})
        if isinstance(result, JsonResponse):
            return result
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def document_delete_api(request):
    """
    删除文件
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"docs": "id"}, {"in_trash": "in_trash"}, in_trash=True)
        if isinstance(params, JsonResponse):
            return params
        from services.document import del_document
        for doc in params["docs"]:
            if doc["is_doc"]:
                update_document({"id": doc['id']}, {"in_trash": True})
            else:
                update_folder({"id": doc['id']}, {"in_trash": True})
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def folder_delete_api(request):
    """
    删除文件夹
    :param request:
    :return:
    """
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"id": "id"}, {"in_trash": "in_trash"}, in_trash=True)
        if isinstance(params, JsonResponse):
            return params
        from services.folder import del_folder
        result = update_folder({"id": params['id']}, {"in_trash": True})
        if isinstance(result, JsonResponse):
            return result
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


@cache_page(60 * 15)
def folder_tree(request):
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, null_params={"parent_folder": "folder", "classes": "classes"})
        if isinstance(params, JsonResponse):
            return params
        folder_tree = path_BFS_tree(params, level=1, max_level=6)
        return success_requests(folder_tree)
    except Exception as e:
        print e
        return err_requests("500", str(e))


def doc_move_api(request):
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"id": "folder", "folder": "id", "is_doc": "is_doc"})
        if isinstance(params, JsonResponse):
            return params
        if params["is_doc"]:
            del params["is_doc"]
            update_docpath({"document__id": params["id"]}, {"folder": params["folder"]})
        else:
            del params["is_doc"]
            update_folderpath({"folder__id": params["id"]}, {"parent_folder": params["folder"]})
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def doc_rename_api(request):
    try:
        body = get_body(request)
        if isinstance(body, JsonResponse):
            return body
        params = get_params(body, {"name": "name", "id": "id", "is_doc": "is_doc"})
        if isinstance(params, JsonResponse):
            return params
        if params["is_doc"]:
            del params["is_doc"]
            update_document({"id": params["id"]}, {"name": params["name"]})
        else:
            del params["is_doc"]
            update_folder({"id": params["id"]}, {"name": params["name"]})
        return success_requests()
    except Exception as e:
        print e
        return err_requests("500", str(e))


def preview_view(request, meta=None):
    if meta:
        return render(request, template_name="document/preview.html", context={"doc_id": meta})
    return render(request, template_name="document/preview.html")
